package com.lyh.web.controller.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lyh.common.annotation.Log;
import com.lyh.common.constant.CacheConstants;
import com.lyh.common.core.controller.BaseController;
import com.lyh.common.core.domain.AjaxResult;
import com.lyh.common.core.domain.BaseEntity;
import com.lyh.common.core.domain.entity.SysUser;
import com.lyh.common.core.domain.model.ForgetPasswordBody;
import com.lyh.common.core.domain.model.SysUserBody;
import com.lyh.common.core.page.TableDataInfo;
import com.lyh.common.core.redis.RedisCache;
import com.lyh.common.enums.BusinessType;
import com.lyh.common.exception.user.CaptchaException;
import com.lyh.common.exception.user.CaptchaExpireException;
import com.lyh.common.utils.SecurityUtils;
import com.lyh.common.utils.StringUtils;
import com.lyh.common.utils.poi.ExcelUtil;
import com.lyh.framework.web.domain.server.Sys;
import com.lyh.framework.web.service.TokenService;
import com.lyh.system.biz.IOrderBiz;
import com.lyh.system.domain.MemberPurchaseInfo;
import com.lyh.system.domain.OperationInfo;
import com.lyh.system.domain.Order;
import com.lyh.system.domain.req.*;
import com.lyh.system.domain.resp.OrderWebResq;
import com.lyh.system.domain.resp.UserCashAdvancePageResp;
import com.lyh.system.domain.resp.UserIncomeResp;
import com.lyh.system.domain.vo.*;
import com.lyh.system.mapper.MemberPurchaseInfoMapper;
import com.lyh.system.mapper.OperationInfoMapper;
import com.lyh.system.mapper.OrderMapper;
import com.lyh.system.mapper.SysUserMapper;
import com.lyh.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户信息
 *
 * @author lyh
 */
@Api(value = "用户账号管理", description = "用户账号管理-在用")
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IOrderBiz orderBiz;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private MemberPurchaseInfoMapper memberPurchaseInfoMapper;

    /**
     * 获取用户列表
     */
    @GetMapping("/pageList")
    @ApiOperation("用户分页管理")
    public TableDataInfo pageList(SysUserBody user) {
        startPage();
        List<SysUser> list = userService.getUserList(user);
        return getDataTable(list);
    }

    /**
     * 获取用户列表
     */
    @GetMapping("/accountPageList")
    @ApiOperation("账户分页管理")
    public TableDataInfo accountPageList(SysUserBody user) {
        startPage();
        List<SysUser> list = userService.getAccountList(user);
        return getDataTable(list);
    }


    /**
     * 根据用户编号获取详细信息
     */
    @GetMapping(value = "/{userId}")
    @ApiOperation("用户详情")
    public AjaxResult getInfo(@PathVariable(value = "userId") Long userId) {
        AjaxResult ajax = AjaxResult.success();
        if (StringUtils.isNotNull(userId)) {
            SysUser sysUser = userService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
        }
        return ajax;
    }

    @Log(title = "新增用户", businessType = BusinessType.INSERT)
    @PostMapping("/saveUser")
    @ApiOperation(value = "新增用户")
    public AjaxResult saveUser(@Validated @RequestBody SysUser user) {
        userService.insertUser(user);
        return success();
    }

    @Log(title = "新增账号", businessType = BusinessType.INSERT)
    @PostMapping("/addAccount")
    @ApiOperation(value = "新增账号")
    public AjaxResult addAccount(@Validated @RequestBody AccountAddReq req) {
        userService.addAccountUser(req);
        return success();
    }

    @Log(title = "修改账号", businessType = BusinessType.INSERT)
    @PostMapping("/editAccountUser")
    @ApiOperation(value = "修改账号")
    public AjaxResult editAccountUser(@Validated @RequestBody AccountEditReq req) {
        userService.editAccountUser(req);
        return success();
    }

    @Log(title = "管理员修改密码", businessType = BusinessType.INSERT)
    @PostMapping("/editAccountPsdByAdmin")
    @ApiOperation(value = "管理员修改密码")
    public AjaxResult editAccountPsdByAdmin(@Validated @RequestBody AccountPsdReq req) {
        userService.editAccountPsdByAdmin(req);
        return success();
    }


    @Log(title = "修改用户", businessType = BusinessType.UPDATE)
    @PostMapping("/updateUser")
    @ApiOperation(value = "修改用户")
    public AjaxResult updateUser(@Validated @RequestBody SysUserEdit user) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(user, sysUser);
        userService.updateUser(sysUser);
        return success();
    }

    @Log(title = "修改用户信息", businessType = BusinessType.UPDATE)
    @PostMapping("/updateUserInfo")
    @ApiOperation(value = "修改用户信息")
    public AjaxResult updateUserInfo(@Validated @RequestBody UpdateUserVo user) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        user.setUserId(sysUser.getUserId());
        userService.updateUserInfo(user);
        return success();
    }

    @Log(title = "修改支付密码", businessType = BusinessType.UPDATE)
    @PostMapping("/updatePayPassword")
    @ApiOperation(value = "修改支付密码")
    public AjaxResult updatePayPassword(@Validated @RequestBody UpdatePayPasswordVo uppv) {
        String uuid = uppv.getUuid();
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        /*if (uuid == null){
            throw new RuntimeException("验证码错误！");
        }
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
        String code = redisCache.getCacheObject(verifyKey);
        if (!code.equals(uppv.getCode())){
            throw new RuntimeException("验证码错误！");
        }*/
        SysUser user = sysUserMapper.selectById(sysUser.getUserId());
        String encryptPassword = SecurityUtils.encryptPassword(uppv.getNewPayPassword());
        user.setPayPassword(encryptPassword);
        sysUserMapper.updateById(user);
        return success();
    }

    @Log(title = "用户删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userId}")
    @ApiOperation(value = "用户删除")
    public AjaxResult deleteUserById(@PathVariable Long userId) {
        if (userId == getUserId()) {
            return error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserById(userId));
    }

    /**
     * 获取用户推广信息
     */
    @GetMapping(value = "/inviteInfo")
    @ApiOperation("用户详情")
    public AjaxResult inviteInfo(@RequestParam(required = false) String type) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        MyInviteVo myInviteVo = userService.inviteInfo(user.getUserId(), type);
        return AjaxResult.success(myInviteVo);
    }

    /**
     * 所有会员列表
     */
    @GetMapping(value = "/allMemberList")
    @ApiOperation("所有会员列表")
    public AjaxResult allMemberList() {//todo
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysUser> sysUsers = sysUserMapper.myIndirectUser(user.getIndirectInviteCodes());
        List<SysUser> users = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getParentId, user.getUserId()));
        users.addAll(sysUsers);
        return AjaxResult.success(users);
    }


    @Log(title = "实名认证", businessType = BusinessType.INSERT)
    @PostMapping("/realFaceCert")
    @ApiOperation(value = "实名认证")
    public AjaxResult realFaceCert(@Validated @RequestBody SysFaceInFoReq req) {
        return userService.realFaceCert(req);
    }

    @Log(title = "修改密码", businessType = BusinessType.UPDATE)
    @PostMapping("/appUpdatePassword")
    @ApiOperation(value = "修改密码")
    public AjaxResult appUpdatePassword(@RequestParam(required = false) String code,
                                        @RequestParam(required = false) String newPassword,
                                        @RequestParam(required = false) String confirmPassword) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        SysUser user = sysUserMapper.selectById(sysUser.getUserId());
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY_PSD + user.getPhonenumber();
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            throw new RuntimeException("验证码错误！");
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new RuntimeException("验证码错误！");
        }

        if (!newPassword.equals(confirmPassword)) {
            throw new RuntimeException("两次输入密码不一致！");
        }
        user.setPassword(SecurityUtils.encryptPassword(newPassword));
        sysUserMapper.updateById(user);
        String userIdKey = tokenService.getUserIdKey(SecurityUtils.getLoginUser().getUserId());
        redisCache.deleteObject(userIdKey);
        return AjaxResult.success("修改成功！");
    }

    @Log(title = "忘记密码", businessType = BusinessType.UPDATE)
    @PostMapping("/forgetPassword")
    @ApiOperation(value = "修改密码")
    public AjaxResult forgetPassword(@RequestBody ForgetPasswordBody fpb) {
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, fpb
                .getUsername()));
        if (sysUser == null) {
            throw new RuntimeException("未查询到此用户！");
        } else if ("1".equals(sysUser.getStatus())) {
            throw new RuntimeException("账号已被停用！");
        }
        if (!sysUser.getPhonenumber().equals(fpb.getTelephone())) {
            throw new RuntimeException("手机号输入不正确！");
        }
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY_PSD + sysUser.getPhonenumber();
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);

        if (captcha == null) {
            throw new RuntimeException("验证码错误！");
        }
        if (!fpb.getCode().equalsIgnoreCase(captcha)) {
            throw new RuntimeException("验证码错误！");
        }

        if (!fpb.getPassword().equals(fpb.getConfirmPassword())) {
            throw new RuntimeException("两次输入密码不一致！");
        }
        sysUser.setPassword(SecurityUtils.encryptPassword(fpb.getPassword()));
        sysUserMapper.updateById(sysUser);
        return AjaxResult.success("修改成功！");
    }


    @Autowired
    OperationInfoMapper operationInfoMapper;

    /**
     * 所有会员列表
     */
    @GetMapping(value = "/getUpdateRecord")
    @ApiImplicitParam(name = "field", value = "字段bo_accountBalance(\"拨余额\"),\n" +
            "    bo_consumerCouponNum(\"拨消费券\"),\n" +
            "    bo_assetEvidenceNum(\"拨资产通证\"),\n" +
            "    bo_integral(\"拨积分\")", required = true, dataType = "String")
    @ApiOperation("获取修改记录")
    public AjaxResult getUpdateRecord(@RequestParam String userId, @RequestParam String field) {//
        List<OperationInfo> operationInfos = operationInfoMapper.selectList(new LambdaQueryWrapper<OperationInfo>()
                .eq(OperationInfo::getUserId, userId)
                .eq(OperationInfo::getOrigin, field)
                .orderByDesc(OperationInfo::getOperationTime));
        return AjaxResult.success(operationInfos);
    }


    /**
     * 获取用户列表
     */
    @GetMapping("/salePageList")
    @ApiOperation("业绩分页管理")
    public TableDataInfo salePageList(SysUserBody user) {
        startPage();
        List<SysUser> list = userService.getSaleUserList(user);
        return getDataTable(list);
    }

    //业绩汇总表

    /**
     * 获取用户列表
     */
    @GetMapping("/countAllMoney")
    @ApiOperation("业绩汇总")
    public AjaxResult countAllMoney(SysUserBody user) {
        return userService.countAllMoney(user);
    }


    @Log(title = "人员业绩表导出", businessType = BusinessType.EXPORT)
    @ApiOperation("人员业绩表导出")
    @PostMapping("/salePageListExport")
    public void export(HttpServletResponse response, @RequestBody SysUserBody user) {
        user.setPageNum(null);
        user.setPageSize(null);
        List<SysUser> list = userService.getSaleUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<>(SysUser.class);
        util.exportExcel(response, list, "人员业绩表导出");
    }

    /**
     * 绑定支付宝和用户实名
     */
    @PostMapping(value = "/bindAliPay")
    @ApiOperation("绑定支付宝和用户实名")
    public AjaxResult bindAliPay(@RequestBody UserBindAliPayVo ubap) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        SysUser user = sysUserMapper.selectById(sysUser.getUserId());
        user.setRealName(ubap.getRealName());
        user.setZfbAccount(ubap.getAliPayAccount());
        sysUserMapper.updateById(user);
        return AjaxResult.success();
    }

    @ApiOperation("个员业绩表")
    @GetMapping("/getUserOrderlist")
    public TableDataInfo getUserOrderlist(UserIncomePageReq req) {
        //直推
        String userId = req.getUserId();
        List<SysUser> sysUsers0 = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getParentId, userId)
                .orderByAsc(BaseEntity::getCreateTime));
        SysUser sysUser = sysUserMapper.selectById(userId);

        List<String> allStrUser = new ArrayList<>();

        //直推
        List<String> userList0 = sysUsers0.stream().map(c -> c.getMemberId()).collect(Collectors.toList());
        List<Long> userIdList = sysUsers0.stream().map(c -> c.getUserId()).collect(Collectors.toList());

        req.setRealList(userIdList);
        String indirectInviteCodes = sysUser.getIndirectInviteCodes();
        //间推
        List<String> memberIds = new ArrayList<>();
        if (StringUtils.isNotEmpty(indirectInviteCodes)) {
            //间推
            List<String> memberIdList = Arrays.asList(indirectInviteCodes.split(","));
            memberIds.addAll(memberIdList);
        }
        //查找本人的
        if (req.getPersonType() == 0) {
            allStrUser.add(sysUser.getMemberId());
            allStrUser.addAll(userList0);
            allStrUser.addAll(memberIds);
        } else if (req.getPersonType() == 1) {
            allStrUser.add(sysUser.getMemberId());
        } else if (req.getPersonType() == 2) {
            allStrUser.addAll(userList0);
        } else if (req.getPersonType() == 3) {
            allStrUser.addAll(memberIds);
        }
        req.setList(allStrUser);
        startPage();
        List<UserIncomeResp> list = orderBiz.orderByUser(req);
        return getDataTable(list);
    }


    @ApiOperation("根据用户获取一条链业务汇总")
    @GetMapping("/getUserOrderRep")
    public AjaxResult getUserOrderRep(String userId) {
        return orderBiz.getUserOrderRep(userId);
    }

    /**
     * APP获取业绩
     */
    @GetMapping("/getAchievements")
    @ApiOperation("APP获取业绩")
    public AjaxResult getAchievements() {
        return AjaxResult.success(userService.getAchievements());
    }

}
